﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CBMS.Interfaces;
using CBMS.Models; 
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace CBMS.Business
{
    public class BaseEntityRepository<TEntity> : IBaseEntityRepository<TEntity>
        where TEntity : EntityObject, new()
    {
        private readonly CBMSEntities _dbContext; 

        public BaseEntityRepository()
        {
            _dbContext = new CBMSEntities(SettingsManager.ConnectString);
        }

        protected CBMSEntities DbContext { get { return _dbContext; } }
        string entitySetName;
        protected string EntitySetName
        {
            get
            {
                if (string.IsNullOrEmpty(entitySetName))
                {
                    entitySetName = RetreveEntitySetName();
                }
                return entitySetName;
            }
            set { entitySetName = value; }
        }

        private string RetreveEntitySetName()
        {
            var entitySetProperty =
               DbContext.GetType().GetProperties()
                   .Single(p => p.PropertyType.IsGenericType && typeof(IQueryable<>)
                   .MakeGenericType(typeof(TEntity)).IsAssignableFrom(p.PropertyType));

            return ((ObjectSet<TEntity>)entitySetProperty.GetValue(DbContext, null)).EntitySet.Name; ;

        }

        protected virtual IQueryable<TEntity> BuildQuery(ObjectQuery<TEntity> query)
        {
            return query;
        }

        public virtual IQueryable<TEntity> List()
        {
            var entitySet = String.Format("[{0}]", EntitySetName);
            var baseQuery = DbContext.CreateQuery<TEntity>(entitySet);
            return BuildQuery(baseQuery);
        }

        public virtual void Add(TEntity entity)
        {
            DbContext.AddObject(EntitySetName, entity);
        }

        public virtual void Attach(TEntity entity)
        {
            DbContext.AttachTo(EntitySetName, entity);
        }

        public virtual void Delete(TEntity entity)
        {
            DbContext.DeleteObject(entity);
        }

        public void SaveChanges()
        { 
            DbContext.SaveChanges();
        }
    }
}
